#!/usr/bin/env python

# ########################################
# TESTS
# ########################################

import unittest
import datetime

from glassvine.handler import GlassCacheHandler
from glassvine.handler import url_filter
from glassvine.properties import props

global ws   # We need this to make a singleton global instance of the 
            # mini-webserver
ws = None # Start by being None.

class test_handler(unittest.TestCase):
    def setUp(self):
        import threading
        import SimpleHTTPServer

        myProp = props()
        config = myProp.load_properties('cache.conf')

        # For tests we don't want to write to FS.
        config['database_file'] = ':memory:'
        config['cache_rules']['.*\.py.*'] = 30

        self.handler = GlassCacheHandler(config)

        class mini_webserver(threading.Thread):
            '''
            This will make a veeeery simple webserver listening on port
            8000, that serves the content from the local directory. Useful
            for testing, *horrible* in a production environment.
            IT's wrapped in a thread because it's normally blocking.
            Thanks for the tip:
            http://www.garyrobinson.net/2004/03/one_line_python.html
            '''
            def run(self):
                import sys
                if len(sys.argv) > 1:
                    sys.argv[1] = 8000
                    SimpleHTTPServer.test()
                
        global ws # Get the singleton global instance
        
        if not ws:
            ws = mini_webserver()
            ws.start()
    
#    def test_forward_text(self):
#        result = self.handler._forward("http://localhost:8000/glassvine/handler.py")
#        
#        self.assert_(result)
#        self.assert_(result['content'])
#        self.assert_(result['headers'])
#        self.assert_(result['type'])
#        self.assert_(result['date_fetched'])
        
#    def test_forward_binary(self):
#        result = self.handler._forward("http://localhost:8000/tests/logo.png")
#        
#        self.assert_(result)
#        self.assert_(result['content'])
#        self.assert_(result['headers'])
#        self.assert_(result['type'])
#        self.assert_(result['date_fetched'])
        
    def test_header_list_to_dict(self):
        list = []
        list.append(('key1', 'value1'))
        
        result = self.handler._header_list_to_dict(list)
        
        self.assertEquals(list[0][1], result['key1'])
        
#    def test_handle_request(self):
#        url = "http://localhost:8000/glassvine/handler.py"
#        result = self.handler.handle_request(url)
#        self.assert_(result)
#        self.assert_(result['headers'])
#        # should be a miss.
#        self.assertEquals(self.handler.local_miss_count, 1)
#        self.assertEquals(self.handler.local_hit_count, 0)
#        
#        result = self.handler.handle_request(url)
#        self.assert_(result)
#        self.assert_(result['headers'])
#        # should be a hit
#        self.assertEquals(self.handler.local_miss_count, 1)
#        self.assertEquals(self.handler.local_hit_count, 1)
#        
#        result = self.handler.handle_request(url)
#        self.assert_(result)
#        self.assert_(result['headers'])
#        # should be a hit
#        self.assertEquals(self.handler.local_miss_count, 1)
#        self.assertEquals(self.handler.local_hit_count, 2)
   
class test_Filter_Fake(unittest.TestCase):
    
    def setUp(self):
        fakeconf = {}
        
        fake_cache = {}
        fake_cache['.*\.png'] = 3000
        fake_cache['.*\.gif'] = -1 # Strange, but valid for tests.
        fake_cache['.*\.html'] = 2500
        fake_cache['.*\.php.*'] = 20
        fake_cache['.*\.asp.*'] = 20
        
        fake_no_cache = []
        
        fake_no_cache.append('https://.*')
        fake_no_cache.append('.*\?.*')
        
        fakeconf['cache_rules'] = fake_cache
        fakeconf['no_cache_rules'] = fake_no_cache
        
        self.filter = url_filter(fakeconf)
        
    def test_cache_matching(self):
        
        self.assertEquals(self.filter.filter('http://localhost/logo.png'), 3000)
        self.assertEquals(self.filter.filter('http://localhost/logo.html'), 2500)
        self.assertEquals(self.filter.filter('http://localhost/dynamic.php'), 20)
        self.assertEquals(self.filter.filter('http://localhost/dynamic.asp'), 20)
        
    def test_no_cache_matching(self):
        self.assertEquals(self.filter.filter('https://www.secret.com'), False)
        self.assertEquals(self.filter.filter('http://localhost/dynamic.php?test=true'), False)
        self.assertEquals(self.filter.filter('http://localhost/dynamic.asp?test=true'), False)
        
    def test_vicious_cache_and_no_cache(self):
        # https should not cache, but .png should cache...
        # By default, we want the cache to be restrictive - cache rules
        # should yield to no_cache rules.
        self.assertEquals(self.filter.filter('https://localhost/logo.png'), False)
        
    def test_is_fresh(self):
        url = "http://localhost/toto.png"
        date = datetime.datetime.now()
        
        result = self.filter.is_fresh(url, date)
        self.assert_(result == True)
        
        url = "http://localhost/toto.gif"
        date = datetime.datetime.now()
        result = self.filter.is_fresh(url, date)
        self.assert_(result == False)

class test_Filter_Functional(unittest.TestCase):
    
    def setUp(self):
        from glassvine.properties import props
        
        with open('cache.conf') as myfile:
            self.content = myfile.readlines()
        self.myprops = props()
        conf = self.myprops._parse_properties(self.content)
        self.filter = url_filter(conf)
        
    #def test_cache_matching(self):
    #    self.assertEquals(self.filter.filter('http://localhost/logo.png'), 3000)
    #    self.assertEquals(self.filter.filter('http://localhost/logo.html'), 2500)
        
        


if __name__ == "__main__" :
    
    unittest.main()

